/**
  ******************************************************************************
  * @file    g_bt.h
  * @version V1.0
  * @date    2021/1/20
  * @brief   bluetooth encapsulation.The HCI protocol refers to YC Dual mode module spec-v4.15
*
  ******************************************************************************
  */
#include "g_bt.h"
#include "g_vbat_ctr.h"
#include "g_sysctrl.h"
#include "g_uart.h"
#include "g_memcp.h"
#include "g_systick.h"

/* Private define ------------------------------------------------------------*/
#define BTTIMEOUT       600
#define BT_BUFSIZE      2048
#define CPU_MHZ         (48*1000000)
#define BT_PRASE_DATALEN 3
/* Private variables ---------------------------------------------------------*/
static uint32_t Bt_StartTick;
static uint8_t hci_cmd_flag;
static uint8_t DownloadPatchFileReply[7] = {0X04, 0X0E, 0X04, 0X01, 0X03, 0XFC, 0X00};
static uint8_t ReolayParse[32] = {0};
static uint8_t CmdRepData[5];

BT_PatchTypedef patch;

uint8_t rcvbuf[BT_BUFSIZE] = {0};

HCI_TypeDef hci_btble_receive_all;      //收到btcode上报事件帧头放入此结构体
uint8_t hci_btble_receive_alldata[200];


HCI_TypeDef hci_rec_btble_event[HCI_BTBLE_EVENTBUF_NUM];    //接收到btcode发送的需要保存数据的事件（除bt\ble data event）
uint8_t hci_rec_btble_eventdata[HCI_BTBLE_EVENTBUF_NUM][HCI_BTBLE_EVENTBUF_LEN];
uint8_t hci_btbleeventbuf_write_index = 0;
uint8_t hci_btbleeventbuf_read_index = 0;


HCI_TypeDef hci_recappdata[HCI_BTBLEDATA_BUF_NUM];          //接收到btcode发送的bt\ble data
uint8_t hci_btble_appdata[HCI_BTBLEDATA_BUF_NUM][HCI_BTBLEDATA_LEN];
uint8_t hci_appdatabuf_write_index = 0;
uint8_t hci_appdatabuf_read_index = 0;


volatile uint8_t hci_rec_data_step = 0; //串口中断内接收蓝牙上报事件阶段，step=0接收帧头(前三个字节) step=1接收data为小于255个字节 step=2为大于255个字节

/*******************************
 * 功能： BT&M0串口通讯初始化
 * 输入： NULL
 * 返回： NUll
 * *****************************/
static void UART2BT_Configuration(uint32_t uartbaud)
{
    UART_InitTypeDef   UART_InitStruct;
    UART_InitStruct.BaudRate  = uartbaud;
    UART_InitStruct.DataBits  = DATABITS_8B;
    UART_InitStruct.StopBits  = STOPBITS_1;
    UART_InitStruct.Parity    = PARITY_NONE;
    UART_InitStruct.FlowCtrl  = FLOWCTRL_NONE;
    UART_InitStruct.RxMode    = MODE_RX_ENABLE;
    UART_InitStruct.SmartCard = SMARTCARD_DISABLE;
    UART_InitStruct.CommMode  = MODE_DUPLEX;

    GPIO_Config(UART2BT_TX_PORT, UART2BT_TX_PIN, UART2BT_Tx_FUNC | PULL_PU);
    GPIO_Config(UART2BT_RX_PORT, UART2BT_RX_PIN, UART2BT_Rx_FUNC | PULL_PU);
    UART_Init(UART2BT_UARTx, &UART_InitStruct);
}


/*******************************
 * 功能： 等待接受数据完成
 * 输入： NULL
 * 返回： NUll
 * *****************************/
void Wait_hci_boot_ack(UART_TypeDef *UARTx, int ack_len)
{
    memset(ReolayParse, 0, sizeof(ReolayParse));
    Bt_StartTick = G_SysTick_GetTick();
    while (UART_ReceiveDataLen(UARTx) < ack_len)
    {
        if (G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT))
        {
#ifdef debug_patch
            MyPrintf("\r\nack timeout\r\n");
#endif
            return;
        }
    }
    UART_ReceiveBuf(UARTx, ReolayParse, ack_len);
#ifdef debug_patch
    printv(ReolayParse, ack_len, "ack");
#endif
}



/*******************************
 * 功能： 复位BT核
 * 输入： NULL
 * 返回： NUll
 * *****************************/
static void Restart_CHipPin(void)
{
#if(BOARD_TYPE <= APP_105_YC3170AB_DOORLOCK_V1_1_BOARD)
    #if (BOARD_TYPE != APP_194_YC3173AB_DOORLOCK_V1_0_BOARD)
    GPIO_Config(GPIOE, GPIO_Pin_1, INPUT);
    GPIO_Config(GPIOE, GPIO_Pin_2, INPUT);
    #endif
    G_LPM_AccessCode(ENABLE);
    MLPM->LDO_EXEN_CTRL.bit.OEN = 1;
    MLPM->LDO_EXEN_CTRL.bit.OUT = 0;
    MLPM->LDO_EXEN_CTRL.bit.GPIO = 0xaa;
    MLPM->LDO_EXEN_CTRL.bit.IE = 0;
    MLPM->LDO_EXEN_CTRL.bit.PD = 0;
    MLPM->LDO_EXEN_CTRL.bit.PU = 0;
    delay_ms(1);
    MLPM->LDO_EXEN_CTRL.bit.OEN = 0;
    MLPM->LDO_EXEN_CTRL.bit.OUT = 1;
    

    delay_ms(1);
    MLPM->LDO_EXEN_CTRL.bit.OEN = 1;
    MLPM->LDO_EXEN_CTRL.bit.OUT = 0;
    MLPM->LDO_EXEN_CTRL.bit.IE = 0;
    MLPM->LDO_EXEN_CTRL.bit.PD = 0;
    MLPM->LDO_EXEN_CTRL.bit.PU = 0;
#else
    GPIO_Config(UART2BT_RTS_SOFT_PORT, UART2BT_RTS_SOFT_PIN, OUTPUT_LOW);
    delay_ms(1);
    GPIO_Config(UART2BT_RTS_SOFT_PORT, UART2BT_RTS_SOFT_PIN, OUTPUT_HIGH);

    delay_ms(1);
    GPIO_Config(UART2BT_RTS_SOFT_PORT, UART2BT_RTS_SOFT_PIN, OUTPUT_LOW);
#endif
}
/*******************************
 * 功能： BT&M0串口通讯初始化
 * 输入： NULL
 * 返回： NUll
 * *****************************/
void _download_btcode(const byte *btcode)
{
    //step1：初始化串口
    UART2BT_Configuration(UART2BTBAUD);
    //step2：RST BT
    Restart_CHipPin();
    uint8_t *pbuf = (uint8_t *)btcode;
    uint32_t dataIndex = 2;
    /*step1:patch传参数据初始化*/
    patch.total_len = GETWORD(pbuf);                /*总的数据长度*/
#ifdef debug_patch
    MyPrintf(" patch.total_len = 0x%x\n", patch.total_len);
#endif
    patch.currentcalc_len = 2;                      /*当前以传输数据长度,初始总数据长度为2byte*/
    while (patch.total_len > patch.currentcalc_len)
    {
        patch.indexlen  = pbuf[dataIndex];              /*初始化第一包数据长度*/
#ifdef debug_patch
        MyPrintf("patch.indexlen = 0x%x\n", patch.indexlen);
#endif
        dataIndex++;
        //更新回复验证码
        DownloadPatchFileReply[3] = pbuf[dataIndex];
        DownloadPatchFileReply[4] = pbuf[dataIndex + 1];
        DownloadPatchFileReply[5] = pbuf[dataIndex + 2];
        for (int i = 0; i < patch.indexlen; i++)
        {
            rcvbuf[i] = pbuf[dataIndex];
            dataIndex++;
        }
        patch.currentcalc_len += (patch.indexlen + 1);
        //串口传输数据
#ifdef debug_patch
        MyPrintf("\nsend[%d]\n", patch.currentcalc_len);
        printv(rcvbuf, patch.indexlen, "");

#endif
//              delay_ms(5);
//        delay_us(1500);
        UART_SendBuf(UART2BT_UARTx, rcvbuf, patch.indexlen);
//        delay_us(1500);
        Wait_hci_boot_ack(UART2BT_UARTx, 7);
        if (memcmp(ReolayParse, DownloadPatchFileReply, 7) == 0)
        {
            if (patch.currentcalc_len >= patch.total_len) //download end
            {
                Wait_hci_boot_ack(UART2BT_UARTx, HCI_TPYE_HEADER);
                if (ReolayParse[0] == 0x02 && ReolayParse[1] == 0x09 && ReolayParse[2] == 0x00)
                {
                    //给变量赋值
                    patch.downfilestatus = TRUE;
#ifdef debug_patch
                    MyPrintf("\npatch download ok\n");
#endif
                    //配置串口接收中断
                    NVIC_EnableIRQ((IRQn_Type)(UART2BT_IRQN));
                    NVIC_SetPriority((IRQn_Type)UART2BT_IRQN, 1);
                    UART_ITConfig(UART2BT_UARTx, UART_IT_RX, ENABLE);
                    hci_rec_data_step = 0;
                    UART_SetRxITNum(UART2BT_UARTx, HCI_TPYE_HEADER);
                    UART_SetITTimeout(UART2BT_UARTx, 100);
                    Set_Soft_RTS_Enable_Rec();
                    break;
                }
                else
                {
#ifdef debug_patch
                    MyPrintf("\npatch no ready\n");
#endif
                    patch.downfilestatus = FALSE;
                    return;
                }
            }
        }
        else
        {
            patch.downfilestatus = FALSE;
            return;
        }
    }
}
/*******************************
 * 功能： 打印HCI数据包
 * 输入： NULL
 * 返回： NUll
 * *****************************/
void PrintHCIPack(HCI_TypeDef *msg, const char *str)
{
    MyPrintf("%s", str);
    MyPrintf("%02x ", msg->type);
    MyPrintf("%02x ", msg->opcode);
    MyPrintf("%02x ", msg->DataLen&0xff);
#if UART_EXT_ENABLE
    MyPrintf("%02x ", msg->DataLen>>8);
#endif
    for (uint16_t cnt = 0; cnt < msg->DataLen; cnt++)
    {
        MyPrintf("%02x ", msg->p_data[cnt]);
    }
    MyPrintf("\n");
}

/*******************************
 * 功能： 清除CMD标志位
 * 输入： NULL
 * 返回： NUll
 * *****************************/
void BT_CMD_FLAG_CLEAR(void)
{
    hci_cmd_flag = 0;
}
/*******************************
 * 功能： 设置CMD标志位
 * 输入： NULL
 * 返回： NUll
 * *****************************/
void BT_CMD_FLAG_SET(void)
{
    hci_cmd_flag = 1;
}
/*******************************
 * 功能： 获取CMD标志位
 * 输入： NULL
 * 返回： hci_cmd_flag
 * *****************************/
uint8_t BT_CMD_FLAG_GET(void)
{
    return hci_cmd_flag;
}

/*******************************
 * 功能： 发送HCI CMD数据
 * 输入： NULL
 * 返回： NUll
 * *****************************/
void  SendCMD(HCI_TypeDef *msg)
{
    msg->type = HCI_CMD;
#ifdef BT_LOG
    PrintHCIPack(msg, "T:");//打印发送包
#endif
    UART_SendBuf(UART2BT_UARTx, (uint8_t *)msg, HCI_TPYE_HEADER);
    if (msg->DataLen > 0)
    {
        UART_SendBuf(UART2BT_UARTx, msg->p_data, msg->DataLen);
    }
}

/*******************************
 * 功能： 蓝牙参数初始化函数
 * 输入： NULL
 * 返回： TRUE: 蓝牙初始化成功
 *        FALSE：蓝牙初始化失败
 * *****************************/
uint8_t BT_Init(void)
{
    hci_cmd_flag = 0; //全局变量问题优化
    Bt_StartTick = 0;

    int i;
    for (i = 0; i < 5; i++)
    {
        CmdRepData[i] = 0;
    }
    for (i = 0; i < BT_BUFSIZE; i++)
    {
        rcvbuf[i] = 0;
    }

    hci_btble_receive_all.p_data =  hci_btble_receive_alldata;
    for (i = 0; i < HCI_BTBLE_EVENTBUF_NUM; i++)
    {
        hci_rec_btble_event[i].p_data = &hci_rec_btble_eventdata[i][0];
    }
    for (i = 0; i < HCI_BTBLEDATA_BUF_NUM; i++)
    {
        hci_recappdata[i].p_data = &hci_btble_appdata[i][0];
    }

    _download_btcode(yc_btcode);
#ifdef BT_ERROR_LOG
    MyPrintf("BT_Init end\n");
#endif
    return patch.downfilestatus;
}

/*******************************
 * 功能： 蓝牙退出低功耗初始化函数
 * 输入： NULL
 * 返回： NULL
 * *****************************/
void BT_Lpm_Wakeup_Init(void)
{
    hci_cmd_flag = 0; //全局变量问题优化
    Bt_StartTick = 0;

    int i;
    for (i = 0; i < 5; i++)
    {
        CmdRepData[i] = 0;
    }
    for (i = 0; i < BT_BUFSIZE; i++)
    {
        rcvbuf[i] = 0;
    }
    hci_btble_receive_all.p_data =  hci_btble_receive_alldata;
    for (i = 0; i < HCI_BTBLE_EVENTBUF_NUM; i++)
    {
        hci_rec_btble_event[i].p_data = &hci_rec_btble_eventdata[i][0];
    }
    for (i = 0; i < HCI_BTBLEDATA_BUF_NUM; i++)
    {
        hci_recappdata[i].p_data = &hci_btble_appdata[i][0];
    }

    UART2BT_Configuration(UART2BTBAUD);
    NVIC_EnableIRQ((IRQn_Type)(UART2BT_IRQN));
    NVIC_SetPriority((IRQn_Type)UART2BT_IRQN, 1);
    UART_ITConfig(UART2BT_UARTx, UART_IT_RX, ENABLE);
    UART_SetRxITNum(UART2BT_UARTx, 1);
    UART_SetITTimeout(UART2BT_UARTx, 100);
}


/*******************************
 * 功能： 设置BT地址
 * 输入： NULL
 * 返回： TRUE:set addr success.
 *        FALSE:set addr failed
 * *****************************/
G_Boolean BT_SetBtAddr(uint8_t *bt_addr)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SET_BT_ADDR;
    msg.DataLen = 6;
    msg.p_data = bt_addr;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT)); //ms
    return FALSE;
}
/*******************************
 * 功能： 设置BLE地址
 * 输入： NULL
 * 返回： TRUE:set addr success.
 *        FALSE:set addr failed
 * *****************************/
G_Boolean BT_SetBleAddr(uint8_t *bt_addr)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SET_BLE_ADDR;
    msg.DataLen = 6;
    msg.p_data = bt_addr;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT)); //ms
    return FALSE;
}
/*******************************
 * 功能： 设置Bt名称
 * 输入： NULL
 * 返回： TRUE:set name success.
 *        FALSE:set name failed
 * *****************************/
G_Boolean BT_SetBtName(uint8_t *bt_name, uint16_t name_len)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SET_BT_NAME;
    msg.DataLen = name_len;
    msg.p_data  = bt_name;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 设置Ble名称
 * 输入： NULL
 * 返回： TRUE:set name success.
 *        FALSE:set name failed
 * *****************************/
G_Boolean BT_SetBleName(uint8_t *ble_name, uint16_t name_len)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SET_BLE_NAME;
    msg.DataLen = name_len;
    msg.p_data  = ble_name;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}


/*******************************
 * 功能： 设置串口流控
 * 输入： ENABLE:set uart_flow
 *        DISABLE:close uart_flow
 * 返回： TRUE:set uart_flow success.
 *        FALSE:set uart_flow failed
 * *****************************/
G_Boolean BT_SetUartFlow(FunctionalState uartflow_ctrl)
{
    if (uartflow_ctrl)
    {
        uint8_t uart_flow = 0x01;
        HCI_TypeDef msg;
        msg.opcode = HCI_CMD_SET_UART_FLOW;
        msg.DataLen = 1;
        msg.p_data  = &uart_flow;
        BT_CMD_FLAG_CLEAR();
        SendCMD(&msg);
        Bt_StartTick = G_SysTick_GetTick();
        do
        {
            if (BT_CMD_FLAG_GET())
            {
                GPIO_Config(GPIOD, GPIO_Pin_11, UART2_RTS | OUTPUT_HIGH);
                return TRUE;
            }
        }
        while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
        return FALSE;
    }
    else
    {
        GPIO_Config(GPIOD, GPIO_Pin_11, UART2_RTS | OUTPUT_LOW);
        return TRUE;
    }
}


/*******************************
 * 功能： 设置蓝牙可发现模式
 * 输入： bt_discoverable: 0--bt_discoverable OFF;1--bt_discoverable ON.
  *       bt_connectability:0--bt_connectability OFF;1--bt_connectability ON.
  *       ble_discoverable:0--ble_discoverable OFF;1--ble_discoverable ON.
 * 返回： TRUE:set visibility success.
  *       FALSE:set visibility failed
 * *****************************/
G_Boolean BT_SetVisibility(uint8_t bt_discoverable, uint8_t bt_connectability, uint8_t ble_discoverable)
{
    HCI_TypeDef msg;
    uint8_t visibility_data = 0;
    if (bt_discoverable == 1)
        visibility_data = visibility_data | 0x01;
    if (bt_connectability == 1)
        visibility_data = visibility_data | 0x02;
    if (ble_discoverable == 1)
        visibility_data = visibility_data | 0x04;

    msg.opcode = HCI_CMD_SET_VISIBILITY;
    msg.DataLen = 0x01;
    msg.p_data = &visibility_data;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 发送Spp数据
 * 输入： NULL
 * 返回：TRUE:send spp data success.
 *       FALSE:send spp data failed
 * *****************************/
G_Boolean BT_SendSppData(uint8_t *spp_data, uint16_t DataLen)
{
    if (DataLen == 0 || DataLen > MAX_BLUETOOTH_DATA_LEN)  return FALSE;
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SEND_SPP_DATA;
    msg.DataLen = DataLen;
    msg.p_data = spp_data;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 发送Ble数据
 * 输入： NULL
 * 返回： TRUE:send ble data success.
 *        FALSE:send ble data failed
 * *****************************/
G_Boolean BT_SendBleData(uint8_t *ble_data, uint16_t DataLen)
{
    if (DataLen < 2 || DataLen > MAX_BLUETOOTH_DATA_LEN)   return FALSE;
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SEND_BLE_DATA;
    msg.DataLen = DataLen;

    msg.p_data = ble_data;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能：获取Bt状态
 * 输入：NULL
 * 返回：bit0:BT 3.0 Can be discover
 *       bit1:BT 3.0 Can be connected
 *       bit2:BT 4.0 Can be discover and connected
 *       bit4:BT 3.0 connected
 *       bit5:BT 4.0 connected
 *       bit7:get status timer out
 * *****************************/
uint8_t Bt_GetBtStatus(void)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_STATUS_REQUEST;
    msg.DataLen = 0;
    msg.p_data = NULL;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return CmdRepData[0];
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT)); //ms
    return 0x80;
}
/*******************************
 * 功能： 设置经典蓝牙配置模式
 * 输入： the paramater can be one of the following value
          0x00:pincode
          0x01:just work
          0x02:passkey
          0x03:confirm
 * 返回： ture or FALSE
 * *****************************/
G_Boolean BT_SetParingMode(uint8_t mode)
{
    uint8_t tmode = mode ;
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SET_PAIRING_MODE;
    msg.DataLen = 1;
    msg.p_data = &tmode;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}

/*******************************
 * 功能： 设置经典蓝牙配对码
 * 输入： NULL
 * 返回： ture or FALSE
 * *****************************/
G_Boolean BT_SetPincode(uint8_t *Pincode, uint8_t DataLen)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SET_PINCODE;
    msg.DataLen = DataLen;
    msg.p_data = Pincode;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 获取BT当前版本
 * 输入： NULL
 * 返回： 返回软件版本号，0表示失败
 * *****************************/
uint32_t BT_GetVersion(void)
{
    HCI_TypeDef msg;
    uint32_t TempVersion = 0;
    msg.opcode = HCI_CMD_VERSION_REQUEST;
    msg.DataLen = 0;
    msg.p_data = NULL;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            TempVersion = (CmdRepData[0] << 8) | (CmdRepData[1]);
            return TempVersion;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return 0;
}
/*******************************
 * 功能： 通知BT断开连接
 * 输入： NULL
 * 返回： TRUE:bt disconnected success.
 *        FALSE:bt disconnected failed
 * *****************************/
G_Boolean BT_BtDisconnect(void)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_BT_DISCONNECT;
    msg.DataLen = 0;
    msg.p_data = NULL;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 通知BLE断开连接
 * 输入： NULL
 * 返回： TRUE:ble disconnected success.
 *        FALSE:ble disconnected failed
 * *****************************/
G_Boolean BT_BleDisconnect(void)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_BLE_DISCONNECT;
    msg.DataLen = 0;
    msg.p_data = NULL;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 下发NVRAM数据
 * 输入： NULL
 * 返回： ture or FALSE
 * *****************************/
G_Boolean BT_SetNVRAM(uint8_t *NvData, int len)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SET_NVRAM;
    msg.DataLen = len;
    msg.p_data = NvData;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 进入睡眠模式
 * 输入： NULL
 * 返回： ture or FALSE
 * *****************************/
G_Boolean BT_EnterSleepMode(void)
{
    uint8_t mode = 0;
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_ENTER_SLEEP_MODE;
    msg.DataLen = 1;
    msg.p_data = &mode;
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return TRUE;
}
/*******************************
 * 功能： 配对模式下的数值比较键匹配
 * 输入： NULL
 * 返回： TRUE:set ConfirmGkey success
 *        FALSE:set ConfirmGkey failed
 * *****************************/
G_Boolean BT_ConfirmGkey(uint8_t isMatching)
{
    HCI_TypeDef msg;
    uint8_t tmismatching = isMatching;
    msg.opcode = HCI_CMD_CONFIRM_GKEY;
    msg.DataLen = 1;
    msg.p_data = &tmismatching;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 设置SPP流控
 * 输入： NULL
 * 返回： TRUE:success
 *        FALSE:failed
 * *****************************/
G_Boolean BT_SetSppFlowcontrol(uint8_t packetNum)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_GET_CREADIT_GIVEN;
    msg.DataLen = 1;
    uint8_t temp_packetNum = packetNum;
    msg.p_data = &temp_packetNum;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    return TRUE;//no event responce
}
/*******************************
 * 功能： 在PASSKEY对中键的比较
 * 输入： NULL
 * 返回： TRUE:set passkey success
 *        FALSE:set passkey  failed
 * *****************************/
G_Boolean BT_PasskeyEntry(uint8_t *key_data)
{
#define PKLEN 0x04
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_PASSKEY_ENTRY;
    msg.DataLen = PKLEN;
    msg.p_data = key_data;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 设置BLE配对模式
 * 输入： NULL
 * 返回： TRUE:set ble paring success
 *        FALSE:set ble paring  failed
 * *****************************/
G_Boolean BT_SetLEParing(uint8_t mode)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_LE_SET_PAIRING;
    msg.DataLen = 1;
    uint8_t temp_mode = mode;
    msg.p_data = &temp_mode;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 设置BLE ADV数据
 * 输入： NULL
 * 返回： TRUE:set ble adv  data success.
 *        FALSE:set ble adv data failed
 * *****************************/
G_Boolean BT_SetLEAdvData(uint8_t *adv_data, int DataLen)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_LE_SET_ADV_DATA;
    msg.DataLen = DataLen;
    msg.p_data = adv_data;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 设置BLE ScanData
 * 输入： NULL
 * 返回： TRUE:set ble scan  data success.
 *        FALSE:set ble scan data failed
 * *****************************/
G_Boolean BT_SetLEScanData(uint8_t *scan_data, int DataLen)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_LE_SET_SCAN_DATA;
    msg.DataLen = DataLen;
    msg.p_data = scan_data;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： Ble发送更新Ble连接参数数据
 * 输入： NULL
 * 返回： TRUE:success.
 *        FALSE:failed
 * *****************************/
G_Boolean BT_SetLESendConnUpdate(uint8_t *data, int len)
{
    if (0x08 != len)
        return FALSE;
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_LE_SEND_CONN_UPDATE_REQ;
    msg.DataLen = len;
    msg.p_data = data;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 设置BLE广播间隔
 * 输入： NULL
 * 返回： TRUE:set ble adv parm success.
 *        FALSE:set ble adv parm failed
 * *****************************/
G_Boolean BT_SetLEAdvInterval(uint16_t ble_adv_interval)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_LE_SET_ADV_PARM;
    msg.DataLen = 2;
    uint8_t ble_adv_interval_buf[2];
    ble_adv_interval_buf[0] = (ble_adv_interval & 0xff);
    ble_adv_interval_buf[1] = ((ble_adv_interval >> 8) & 0xff);
    msg.p_data = ble_adv_interval_buf;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 设置RejectJustWork
 * 输入： NULL
 * 返回： TRUE:set ble scan  data success.
 *        FALSE:set ble scan data failed
 * *****************************/
G_Boolean BT_RejectJustWork(uint8_t justwork)
{
    uint8_t td = justwork;
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_REJECT_JUSTWORK;
    msg.DataLen = 0x01;
    msg.p_data = &td;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 设置FixedPasskey
 * 输入： NULL
 * 返回： TRUE:set fixed passkey  success.
 *        FALSE:set ble fixed passkey failed
 * *****************************/
G_Boolean BT_Set_FixedPasskey(uint8_t *key)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_LE_SET_FIXED_PASSKEY;
    msg.DataLen = 0x05;
    msg.p_data = key;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 设置COD
 * 输入： NULL
 * 返回： TRUE:success.
 *        FALSE:failed
 * *****************************/
G_Boolean BT_SetCOD(uint8_t *bt_cod)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SET_COD;
    msg.DataLen = 3;
    msg.p_data = bt_cod;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT)); //ms
    return FALSE;
}
/*******************************
 * 功能： 设置Tx发射功率
 * 输入： NULL
 * 返回： TRUE:set SetTxPower  success.
 *        FALSE:set SetTxPower failed
 * *****************************/
G_Boolean BT_SetTxPower(uint8_t power)
{
    uint8_t tpower = power;
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_SET_TX_POWER;
    msg.DataLen = 0x01;
    msg.p_data = &tpower;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 删除BT服务
 * 输入： NULL
 * 返回： TRUE:success.
 *        FALSE:failed
 * *****************************/
G_Boolean BT_DeleteService(void)
{
    uint8_t data[2] = {0x08, 0x00};
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_DELETE_CUSTOMIZE_SERVICE;
    msg.DataLen = 2;
    msg.p_data = data;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 添加BLE服务
 * 输入： NULL
 * 返回： FALSE:failed
  *       other:Service handle
 * *****************************/
uint16_t BT_AddBleService(uint8_t *ble_service_uuid, uint16_t service_uuid_len)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_ADD_SERVICE_UUID;
    msg.DataLen = service_uuid_len;
    msg.p_data  = ble_service_uuid;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return (uint16_t)(CmdRepData[0] | (CmdRepData[1] << 8));
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 添加BLE特征值
 * 输入： NULL
 * 返回： FALSE:failed
 *        other:Characteristic handle
 * *****************************/
uint16_t BT_AddBleCharacteristic(uint8_t *ble_Characteristic_uuid, uint16_t service_Characteristic_payload_len)
{
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_ADD_CHARACTERISTIC_UUID;
    msg.DataLen = service_Characteristic_payload_len;
    msg.p_data  = ble_Characteristic_uuid;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return (uint16_t)(CmdRepData[0] | (CmdRepData[1] << 8));
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}
/*******************************
 * 功能： 更改UART波特率
 * 输入： NULL
 * 返回： NUll
 * *****************************/
G_Boolean BT_SetUartBaud(int baud)
{
    HCI_TypeDef msg;
    uint8_t uartbaud[6];
    for (int i = 0; i < 6; i++)
    {
        uartbaud[5 - i] = ((baud % 10) + '0');
        baud /= 10;
    }
    msg.opcode = HCI_CMD_SET_UART_BAUD;
    msg.DataLen = 6;
    msg.p_data  = uartbaud;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            UART2BT_Configuration(921600);
            NVIC_EnableIRQ((IRQn_Type)(UART2BT_IRQN));
            NVIC_SetPriority((IRQn_Type)UART2BT_IRQN, 1);
            UART_ITConfig(UART2BT_UARTx, UART_IT_RX, ENABLE);
            hci_rec_data_step = 0;
            UART_SetRxITNum(UART2BT_UARTx, 3);
            UART_SetITTimeout(UART2BT_UARTx, 100);
            Set_Soft_RTS_Enable_Rec();
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT + 500));
    return FALSE;
}

/*******************************
 * 功能： Ble低功耗开关
 * 输入： mode:0 close lpm_mode, 1 set lpm_mode
 * 返回： TRUE:set lpm_mode success.
 *        FALSE:set lpm_mode failed
 * *****************************/
G_Boolean BT_SetLpmMode(uint8_t mode)
{
    HCI_TypeDef msg;
    uint8_t temp_mode = mode;
    msg.opcode = HCI_CMD_SET_LPM_MODE;
    msg.DataLen = 1;
    msg.p_data  = &temp_mode;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT));
    return FALSE;
}

/*******************************
 * 功能： BT数据解析
 * 输入： NULL
 * 返回： NUll
 * *****************************/
void BT_ParseBTData(void)
{
    if (hci_btble_receive_all.type == HCI_EVENT)
    {
        switch (hci_btble_receive_all.opcode)
        {
        case HCI_EVENT_BT_CONNECTED:
        case HCI_EVENT_BLE_CONNECTED:
        case HCI_EVENT_BT_DISCONNECTED:
        case HCI_EVENT_BLE_DISCONNECTED:
        case HCI_EVENT_PAIRING_COMPLETED:
        case HCI_EVENT_LE_PAIRING_STATE:
        case HCI_EVENT_BB_DISCONNECT:
        case HCI_EVENT_BT_NAME:
        case HCI_EVENT_GET_PASSKEY:
        case HCI_EVENT_NVRAM_CHANGED:
        case HCI_EVENT_GKEY:
            hci_btbleeventbuf_write_index++;
            if (hci_btbleeventbuf_write_index >= HCI_BTBLE_EVENTBUF_NUM)
            {
                hci_btbleeventbuf_write_index = 0;
            }
            memcpy(&hci_rec_btble_event[hci_btbleeventbuf_write_index], (uint8_t *)&hci_btble_receive_all, 3);
            memcpy(&hci_rec_btble_event[hci_btbleeventbuf_write_index].p_data[0], (uint8_t *)&hci_btble_receive_all.p_data[0], hci_btble_receive_all.DataLen);
            break;

        case HCI_EVENT_CMD_COMPLETE:
            switch (hci_btble_receive_all.p_data[0])
            {
            case HCI_CMD_SET_BT_ADDR:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SET_BLE_ADDR:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SET_VISIBILITY:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SET_BT_NAME:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;
            case HCI_CMD_SET_BLE_NAME:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SEND_SPP_DATA:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SEND_BLE_DATA:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SET_PAIRING_MODE:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SET_PINCODE:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;
            case HCI_CMD_SET_UART_BAUD:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;
            case HCI_CMD_VERSION_REQUEST:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                    CmdRepData[0] = hci_btble_receive_all.p_data[2];
                    CmdRepData[1] = hci_btble_receive_all.p_data[3];
                }
                break;

            case HCI_CMD_LE_SET_PAIRING:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_BT_DISCONNECT:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;
                
            case HCI_CMD_READ_CHIP_DATA:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;
                
            case HCI_CMD_BLE_DISCONNECT:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;
            case HCI_CMD_SET_NVRAM:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SET_UART_FLOW:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_ENTER_SLEEP_MODE:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_CONFIRM_GKEY:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SET_LPM_MODE:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_PASSKEY_ENTRY:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_LE_SET_ADV_DATA:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_LE_SET_SCAN_DATA:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_LE_SEND_CONN_UPDATE_REQ:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;
            case HCI_CMD_LE_SET_ADV_PARM:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SET_TX_POWER:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_REJECT_JUSTWORK:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SET_COD:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_DELETE_CUSTOMIZE_SERVICE:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_LE_SET_FIXED_PASSKEY:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_CONNECT_BNEP:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_CONNECT_TCP:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_DISCONNECT_TCP:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_BNEP_SEND_TCP_DATA:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SEND_UDP_DATA:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_SEND_BIG_DATA:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;

            case HCI_CMD_DNS_REQ:
                if (!hci_btble_receive_all.p_data[1])
                {
                    BT_CMD_FLAG_SET();
                }
                break;
            default:
#ifdef BT_ERROR_LOG
                MyPrintf("bt 06 cmd err\n");
#endif
                break;
            }
            break;

        case HCI_EVENT_I_AM_READY:
            BT_CMD_FLAG_SET();
            break;

        case HCI_EVENT_STAUS_RESPONSE:
            BT_CMD_FLAG_SET();
            CmdRepData[0] = hci_btble_receive_all.p_data[0];
            break;

        case HCI_EVENT_UUID_HANDLE:
            BT_CMD_FLAG_SET();
            CmdRepData[0] = hci_btble_receive_all.p_data[0];
            CmdRepData[1] = hci_btble_receive_all.p_data[1];
            break;

        case HCI_EVENT_BIG_DATA_FINISH:
            if (hci_btble_receive_all.p_data[0] == 0x00)
            {
                BT_CMD_FLAG_SET();
            }
            break;

        case HCI_EVENT_BIG_DATA_STATUS:
            if (hci_btble_receive_all.p_data[0] == 0x03 || hci_btble_receive_all.p_data[0] == 0x04)
            {
                BT_CMD_FLAG_SET();
            }
            break;

        default:
#ifdef BT_ERROR_LOG
            MyPrintf("bt event err");
#endif
            break;
        }
    }
    else
    {
#ifdef BT_ERROR_LOG
        MyPrintf("bt 02 err");
#endif
    }
}
/*******************************
 * 功能： 通知BT可以发送数据
 * 输入： NULL
 * 返回： NULL
 * *****************************/
void Set_Soft_RTS_Enable_Rec(void)
{
    MGPIO->CTRL.reg[GPIO_GetNum(UART2BT_RTS_SOFT_PORT, UART2BT_RTS_SOFT_PIN)] = OUTPUT_LOW;
}
/*******************************
* 功能： 通知BT不可以发送数据
 * 输入： NULL
 * 返回： NULL
 * *****************************/
void Set_Soft_RTS_Disable_Rec(void)
{
    MGPIO->CTRL.reg[GPIO_GetNum(UART2BT_RTS_SOFT_PORT, UART2BT_RTS_SOFT_PIN)] = OUTPUT_HIGH;
}
/*******************************
 * 功能： 检查串口接收蓝牙buf是否将要满、检测hci_buf是否将要满，如果任一要满，拉起gpio，
 *        通知bt不要再发送数据
 * 输入： NULL
 * 返回： 0-ok 1、2-full
 * *****************************/
uint8_t Check_RecBT2M0Buf_Full(void)
{
    uint32_t num = 0;

    //检测串口buf
    num = uart2_DMA_buf_len - UART_ReceiveDataLen(UART2BT_UARTx);
    if (num <= 1024)
    {
        Set_Soft_RTS_Disable_Rec();
        return 1;
    }

    if ((hci_btble_receive_all.opcode == HCI_EVENT_SPP_DATA_RECEIVED) || (hci_btble_receive_all.opcode == HCI_EVENT_BLE_DATA_RECEIVED))
    {
        //检查hci_buf
        if (hci_appdatabuf_write_index >= hci_appdatabuf_read_index)
        {
            num = hci_appdatabuf_write_index - hci_appdatabuf_read_index;
        }
        else
        {
            num = hci_appdatabuf_write_index + HCI_BTBLEDATA_BUF_NUM - hci_appdatabuf_read_index;
        }
        //
        if (num >= (HCI_BTBLEDATA_BUF_NUM - 2))
        {
            Set_Soft_RTS_Disable_Rec();
            return 2;
        }
    }
    return 0;
}

/*******************************
 * 功能： 检查串口接收蓝牙buf、检测hci_buf是否可以接收数据，
 *        通知bt可以发送数据
 * 输入： NULL
 * 返回： 0-ok 1、2-full
 * *****************************/
void Check_RecBT2M0Buf_Free(void)
{
    uint32_t num = 0;
    //检测串口buf
    num = uart2_DMA_buf_len - UART_ReceiveDataLen(UART2BT_UARTx);
    if (num <= 1024) //串口buf有空间
    {
        return;
    }

    //检查hci_buf
    if (hci_appdatabuf_write_index >= hci_appdatabuf_read_index)
    {
        num = hci_appdatabuf_write_index - hci_appdatabuf_read_index;
    }
    else
    {
        num = hci_appdatabuf_write_index + HCI_BTBLEDATA_BUF_NUM - hci_appdatabuf_read_index;
    }
    if (num < (HCI_BTBLEDATA_BUF_NUM - 2))
    {
        Set_Soft_RTS_Enable_Rec();
    }

    return;
}

/*******************************
 * 功能： MEMCPY DMA寄存器初始化
 * 输入： MEMCP-DMA编号、MEMCP_InitStruct-DMA参数结构体
 * 返回： NULL
 * *****************************/
void MEMCP_Init_Lock_ReadAddr(DMA_TypeDef *MEMCP, MEMCP_InitTypeDef *MEMCP_InitStruct)
{
    _ASSERT(IS_MEMCP(MEMCP));

    MEMCP->CTRL.bit.RESET = 1;
    MEMCP->CTRL.bit.RESET = 0;
    MEMCP->SRC_ADDR.reg = (MEMCP_InitStruct->SRC);
    MEMCP->DEST_ADDR.reg = (MEMCP_InitStruct->DES);
    MEMCP->LEN_LOW.bit.RX_LEN_L = MEMCP_InitStruct->D_LEN;
    MEMCP->LEN_LOW.bit.TX_LEN_L = MEMCP_InitStruct->S_LEN;

    MEMCP->CTRL.bit.RADDR_LOCK = 1;
}

/*******************************
 * 功能： MEMCPY DMA 参数初始化、启动、等待copy完成
 * 输入： saddr-源地址 s_len-源长度 daddr-目的地址 d_len-目的长度
 * 返回： NULL
 * *****************************/
void MEMCP_Configuration(unsigned int saddr, unsigned int s_len, unsigned int daddr, unsigned int d_len)
{
    MEMCP_InitTypeDef MEMCP_InitStruct;

    MEMCP_InitStruct.DES = daddr;
    MEMCP_InitStruct.D_LEN = d_len;
    MEMCP_InitStruct.SRC = saddr;
    MEMCP_InitStruct.S_LEN = s_len;
    MEMCP_Init_Lock_ReadAddr(MDMA_MEMCP, &MEMCP_InitStruct);
    MEMCP_Cmd(MDMA_MEMCP);
    while (!(MEMCP_GETITStatus(MDMA_MEMCP) & 1));
}

/*******************************
 * 功能： 蓝牙数据中断处理函数
 * 输入： NULL
 * 返回： NUll
 * *****************************/
void UART2_IRQHandler(void)
{
    static uint16_t num = 0;
    static uint8_t data_len = 255;
    static uint16_t count = 0;
    if (hci_rec_data_step == 0)
    {
        if(UART_ReceiveDataLen(UART2BT_UARTx) >= BT_PRASE_DATALEN)
        {
            UART_ReceiveBuf(UART2BT_UARTx, (uint8_t *)&hci_btble_receive_all, HCI_TPYE_HEADER);
            Check_RecBT2M0Buf_Full();

            if (hci_btble_receive_all.DataLen == 0)
            {
                BT_ParseBTData();
                num = HCI_TPYE_HEADER;
            }
            else
            {
                num = hci_btble_receive_all.DataLen;
                hci_rec_data_step = 1;              
                if(num>255)
                {
                    UART_SetRxITNum(UART2BT_UARTx, 0);
                    UART_SetRxITNum(UART2BT_UARTx, data_len);
                    num = num-255;
                                  
                }
                else
                {   
                    data_len = num;
                    UART_SetRxITNum(UART2BT_UARTx, 0);
                    UART_SetRxITNum(UART2BT_UARTx, data_len);
                    num = 0;
                }
            }

#ifdef BT_LOG        
#if UART_EXT_ENABLE
        MyPrintf("R:%02X %02X %02X %02X ", hci_btble_receive_all.type, hci_btble_receive_all.opcode, hci_btble_receive_all.DataLen&0xff, hci_btble_receive_all.DataLen>>8);
#else
        MyPrintf("R:");
        MyPrintf("%02X %02X %02X ", hci_btble_receive_all.type, hci_btble_receive_all.opcode, hci_btble_receive_all.DataLen);
#endif
#endif
        }
    }
    else 
    {
        if (UART_ReceiveDataLen(UART2BT_UARTx) >= data_len)
        {
            switch (hci_btble_receive_all.opcode)
            {
            case HCI_EVENT_SPP_DATA_RECEIVED:
            case HCI_EVENT_BLE_DATA_RECEIVED:
                hci_appdatabuf_write_index++;
                if (hci_appdatabuf_write_index >= HCI_BTBLEDATA_BUF_NUM)
                {
                    hci_appdatabuf_write_index = 0;
                }
                memcpy(&hci_recappdata[hci_appdatabuf_write_index], (uint8_t *)&hci_btble_receive_all, HCI_TPYE_HEADER);
                MEMCP_Configuration(MUART2_BASE + 8, data_len, (uint32_t)hci_recappdata[hci_appdatabuf_write_index].p_data+count*255, data_len);
                count++;
#ifdef BT_LOG
                for (int i = 0; i < hci_btble_receive_all.DataLen; i++)
                {
                    MyPrintf("%02X ", hci_recappdata[hci_appdatabuf_write_index].p_data[i]);
                }
                MyPrintf("\r\n ");
#endif
                break;
            default:
                UART_ReceiveBuf(UART2BT_UARTx, hci_btble_receive_all.p_data, data_len);

#ifdef BT_LOG
                for (int i = 0; i < hci_btble_receive_all.DataLen; i++)
                {
                    MyPrintf("%02X ", hci_btble_receive_all.p_data[i]);
                }
                MyPrintf("\r\n ");
#endif
                BT_ParseBTData();
                break;
            }
        }
        if(num >255)
        {
            UART_SetRxITNum(UART2BT_UARTx, 0);
            UART_SetRxITNum(UART2BT_UARTx, data_len);
            num =num-255;           
            if (hci_appdatabuf_write_index == 0)
            {
                hci_appdatabuf_write_index = HCI_BTBLEDATA_BUF_NUM-1;
            }
            else
            {
                hci_appdatabuf_write_index--;            
            }
        }
        else if (num == 0)
        {
            count = 0;
            data_len =255;
            hci_rec_data_step = 0;
            UART_SetRxITNum(UART2BT_UARTx, HCI_TPYE_HEADER);           
        }
        else 
        {   
            data_len = num;        
            UART_SetRxITNum(UART2BT_UARTx, 0);
            UART_SetRxITNum(UART2BT_UARTx, data_len);
            num = 0;
            if (hci_appdatabuf_write_index == 0)
            {
                hci_appdatabuf_write_index = HCI_BTBLEDATA_BUF_NUM-1;
            }
            else
            {
                hci_appdatabuf_write_index--;            
            }         
        }       
    }  
}


G_Boolean BT_ReadBtRssi(void)
{
    uint8_t bt_rssi_data[3] = {0x01, 0x18, 0x00};
    HCI_TypeDef msg;
    msg.opcode = HCI_CMD_READ_CHIP_DATA;
    msg.DataLen = 3;
    msg.p_data = bt_rssi_data;
    BT_CMD_FLAG_CLEAR();
    SendCMD(&msg);
    Bt_StartTick = G_SysTick_GetTick();
    do
    {
        if (BT_CMD_FLAG_GET())
        {
            return TRUE;
        }
    }
    while (!G_SysTick_IsTimeOut(Bt_StartTick, BTTIMEOUT)); //ms
    return FALSE;
}

